package com.jfs.security.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jfs.constant.SecurityConstant;
import com.jfs.entity.OperationLog;
import com.jfs.mapper.OperationLogMapper;
import com.jfs.security.dto.OperationLogDto;
import com.jfs.security.service.OperationLogService;
import com.jfs.security.vo.LogListVo;
import com.jfs.security.vo.LoginUserEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @Description 日志实现层
 * @E-mail cwm3412638@163.com
 * @Author cwm
 * @Date 2022/8/8
 */
@Service
@Slf4j
public class OperationLogServiceImpl extends ServiceImpl<OperationLogMapper, OperationLog> implements OperationLogService {
    /**
     * 保存用户日志
     *
     * @param operationLog
     */
    @Async
    @Transactional
    public void saveOperationLog(OperationLog operationLog) {
        this.save(operationLog);
    }

    @Override
    public IPage<OperationLogDto> list(LoginUserEntity loginUserEntity, LogListVo logListVo) {
        List<OperationLogDto> list = new ArrayList<>();
        List<OperationLog> records = null;
        Page<OperationLog> page = null;
        Page<OperationLogDto> operationLogDtoPage = null;
        if (Objects.nonNull(loginUserEntity)) {
            if (Objects.nonNull(loginUserEntity.getRole())) {
                if (SecurityConstant.SUPER_ADMIN.equals(loginUserEntity.getRole().getRoleKey())) {
                    page = this.page(new Page<>(logListVo.getPageNum(), logListVo.getPageSize()), Wrappers.<OperationLog>lambdaQuery()
                            .and((StrUtil.isNotEmpty(logListVo.getRequestMethod())||StrUtil.isNotEmpty(logListVo.getSearchKey())),warp ->
                                    //根据亲求方式查询
                                    warp.like(StrUtil.isNotEmpty(logListVo.getRequestMethod()), OperationLog::getRequestMethod, logListVo.getRequestMethod())
                                            .or()
                                            //根据关键字搜索
                                            .like(StrUtil.isNotEmpty(logListVo.getSearchKey()), OperationLog::getTitle, logListVo.getSearchKey())
                            )
                            .ge(Objects.nonNull(logListVo.getStartTime()), OperationLog::getExecuteTime, logListVo.getStartTime())
                            //结束时间
                            .le(Objects.nonNull(logListVo.getEndTime()), OperationLog::getExecuteTime, logListVo.getEndTime())
                            .orderByDesc(OperationLog::getExecuteTime));
                    records = page.getRecords();
                } else {
                    page = this.page(new Page<>(logListVo.getPageNum(), logListVo.getPageSize()),
                            Wrappers.<OperationLog>lambdaQuery()
                                    .eq(OperationLog::getUserName, loginUserEntity.getUsername())
                                    .and((StrUtil.isNotEmpty(logListVo.getRequestMethod())||StrUtil.isNotEmpty(logListVo.getSearchKey())),warp ->
                                            //根据亲求方式查询
                                            warp.like(StrUtil.isNotEmpty(logListVo.getRequestMethod()), OperationLog::getRequestMethod, logListVo.getRequestMethod())
                                                    .or()
                                                    //根据关键字搜索
                                                    .like(StrUtil.isNotEmpty(logListVo.getSearchKey()), OperationLog::getTitle, logListVo.getSearchKey())
                                    )
                                    .ge(Objects.nonNull(logListVo.getStartTime()), OperationLog::getExecuteTime, logListVo.getStartTime())
                                    //结束时间
                                    .le(Objects.nonNull(logListVo.getEndTime()), OperationLog::getExecuteTime, logListVo.getEndTime())
                                    .orderByDesc(OperationLog::getExecuteTime)
                    );

                }
            }
        }
        if (CollectionUtil.isNotEmpty(records)) {
            for (OperationLog operationLog : records
            ) {
                OperationLogDto operationLogDto = new OperationLogDto();
                BeanUtil.copyProperties(operationLog, operationLogDto);
                list.add(operationLogDto);
            }
            operationLogDtoPage = new Page<>();
            BeanUtil.copyProperties(page, operationLogDtoPage);
            operationLogDtoPage.setRecords(list);
            return operationLogDtoPage;
        }
        return operationLogDtoPage;
    }

    @Override
    @Transactional
    public void clean(LoginUserEntity loginUserEntity) {
        if (Objects.nonNull(loginUserEntity)) {
            if (Objects.nonNull(loginUserEntity.getRole())) {
                if (SecurityConstant.SUPER_ADMIN.equals(loginUserEntity.getRole().getRoleKey())) {
                    this.remove(Wrappers.<OperationLog>lambdaQuery());
                } else {
                    this.remove(Wrappers.<OperationLog>lambdaQuery().eq(OperationLog::getUserName, loginUserEntity.getUsername()));
                }
            }
        }
    }
}
